package com.ld.wms.business.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ld.wms.business.user.mapper.RoleMapper;
import com.ld.wms.business.user.mapper.UserAccountMapper;
import com.ld.wms.business.user.mapper.UserAccountRoleMapper;
import com.ld.wms.business.user.model.UserAccountModel;
import com.ld.wms.business.user.model.UserAccountRoleModel;
import com.ld.wms.business.user.service.MenuService;
import com.ld.wms.business.user.service.UserAccountService;
import com.ld.wms.business.user.vo.req.UserAccountReqVo;
import com.ld.wms.business.user.vo.req.UserLoginReqVo;
import com.ld.wms.business.user.vo.resp.MenuTreeRespVo;
import com.ld.wms.business.user.vo.resp.RoleRespVo;
import com.ld.wms.business.user.vo.resp.UserAccountRespVo;
import com.ld.wms.business.user.vo.resp.UserLoginRespVo;
import com.ld.wms.common.CommonConstant;
import com.ld.wms.common.vo.GeneratePageListVo;
import com.ld.wms.common.vo.TokenInfoRespVo;
import com.ld.wms.exception.BusinessException;
import com.ld.wms.sysenum.DeleteFlagEnum;
import com.ld.wms.sysenum.ResultResponseEnum;
import com.ld.wms.sysenum.UserStatusEnum;
import com.ld.wms.utils.CommonUtils;
import com.ld.wms.utils.JWTUtils;
import com.ld.wms.utils.MD5Utils;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author wangfeng
 * @since 2024-04-12
 */
@Slf4j
@Service
public class UserAccountServiceImpl extends ServiceImpl<UserAccountMapper, UserAccountModel> implements UserAccountService {

    @Autowired
    private JWTUtils jwtUtils;

    @Autowired
    private UserAccountMapper userAccountMapper;

    @Autowired
    private UserAccountRoleMapper userAccountRoleMapper;

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private MenuService menuService;

    @Override
    public void add(UserAccountReqVo reqVo) {
        Long currentUserAccountId = jwtUtils.getCurrentUserAccountId();
        UserAccountModel userAccountModel = new UserAccountModel();
        BeanUtils.copyProperties(reqVo, userAccountModel);
        // 设置用户名密码
        String password = CommonConstant.USER_DEFAULT_PASSWORD;
        String salt = CommonUtils.getPwdSalt();
        String encryptPassword = getUserPassword(salt, password);
        userAccountModel.setSalt(salt);
        userAccountModel.setPassword(encryptPassword);
        userAccountModel.setCreateBy(currentUserAccountId);
        userAccountModel.setCreateTime(new Date());
        userAccountModel.setStatus(UserStatusEnum.NORMAL.getStatus());
        userAccountModel.setDelFlag(DeleteFlagEnum.NO.getCode());
        userAccountModel.setHeadImage("https://www.cells88.com/wp-content/uploads/2023/11/2023110300595934.png");
        userAccountMapper.insert(userAccountModel);
        log.debug("add userAccountModel:{}", userAccountModel);
        // 添加用户和角色的关系
        addRole(userAccountModel.getId(), reqVo.getRoleIdList());
    }

    @Override
    public void update(UserAccountReqVo reqVo) {
        Long currentUserAccountId = jwtUtils.getCurrentUserAccountId();
        UserAccountModel userAccountModel = new UserAccountModel();
        BeanUtils.copyProperties(reqVo, userAccountModel);
        userAccountModel.setUpdateBy(currentUserAccountId);
        userAccountModel.setUpdateTime(new Date());
        userAccountMapper.updateById(userAccountModel);
        // 删除原来用户角色关联关系
        Map<String, Object> columnMap = new HashMap<>();
        columnMap.put(UserAccountRoleModel.USER_ACCOUNT_ID, reqVo.getId());
        userAccountRoleMapper.deleteByMap(columnMap);
        // 添加用户和角色的关系
        addRole(userAccountModel.getId(), reqVo.getRoleIdList());
    }

    @Override
    public void delete(Long id) {
        userAccountMapper.deleteByDelFlag(id);
    }

    @Override
    public UserAccountRespVo getById(Long id) {
        UserAccountRespVo userAccountRespVo = new UserAccountRespVo();
        UserAccountModel userAccountModel = userAccountMapper.selectById(id);
        BeanUtils.copyProperties(userAccountModel, userAccountRespVo);
        // 查询某个用户所有角色id
        QueryWrapper<UserAccountRoleModel> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(UserAccountRoleModel.USER_ACCOUNT_ID, id);
        List<UserAccountRoleModel> userAccountRoleModelList = userAccountRoleMapper.selectList(queryWrapper);
        List<Long> roleIdList = userAccountRoleModelList.stream().map(UserAccountRoleModel::getRoleId).toList();
        userAccountRespVo.setRoleIdList(roleIdList);
        return userAccountRespVo;
    }

    @Override
    public GeneratePageListVo<UserAccountRespVo> getPageList(String accountName, String realName, Integer status, String mobile, Integer current, Integer size) {
        Page<UserAccountRespVo> iPage = new Page<>(current, size);
        IPage<UserAccountRespVo> iPageList = userAccountMapper.selectPageList(iPage, accountName, realName, status, mobile);

        List<UserAccountRespVo> userAccountRespVoList = iPageList.getRecords();

        for (UserAccountRespVo userAccountRespVo : userAccountRespVoList) {
            List<RoleRespVo> roleRespVoList = roleMapper.selectListByUserAccountId(userAccountRespVo.getId());
            userAccountRespVo.setRoleList(roleRespVoList);
        }
        return new GeneratePageListVo<>(iPageList);
    }

    @Override
    public UserLoginRespVo userLogin(UserLoginReqVo reqVo) {
        UserLoginRespVo userLoginRespVo = new UserLoginRespVo();
        QueryWrapper<UserAccountModel> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(UserAccountModel.ACCOUNT_NAME, reqVo.getAccountName());
        queryWrapper.eq(UserAccountModel.DEL_FLAG, DeleteFlagEnum.NO.getCode());
        UserAccountModel userAccountModel = userAccountMapper.selectOne(queryWrapper);
        if (ObjectUtils.isEmpty(userAccountModel)) {
            throw new BusinessException("用户不存在！");
        }

        // 判断用户密码是否匹配
        String encryptPassword = getUserPassword(userAccountModel.getSalt(), reqVo.getPassword());
        String dbPassword = userAccountModel.getPassword();
        if (!encryptPassword.equals(dbPassword)) {
            throw new BusinessException("用户名密码错误！");
        }
        String token = jwtUtils.createToken(userAccountModel.getId(), userAccountModel.getAccountName());
        userLoginRespVo.setUserToken(token);
        userLoginRespVo.setUserAccount(userAccountModel.getAccountName());
        userLoginRespVo.setId(userAccountModel.getId());
        userLoginRespVo.setRealName(userAccountModel.getRealName());
        return userLoginRespVo;
    }

    @Override
    public UserAccountRespVo getCurrentUser() {
        UserAccountRespVo userAccountRespVo = new UserAccountRespVo();
        TokenInfoRespVo tokenInfo = jwtUtils.getTokenInfo();
        log.debug("getCurrentUser:{}", tokenInfo);
        Long id = tokenInfo.getUserAccountId();
        UserAccountModel userAccountModel = userAccountMapper.selectById(id);
        BeanUtils.copyProperties(userAccountModel, userAccountRespVo);
        List<MenuTreeRespVo> currentMenuTree = menuService.getCurrentMenuList(0);
        List<MenuTreeRespVo> buttonList = menuService.getCurrentMenuList(1);
        userAccountRespVo.setMenuList(currentMenuTree);
        userAccountRespVo.setButtonList(buttonList);
        return userAccountRespVo;
    }

    @Override
    public void updatePassword(UserAccountReqVo reqVo) {
        Long currentUserAccountId = jwtUtils.getCurrentUserAccountId();
        UserAccountModel userAccountModel = userAccountMapper.selectById(currentUserAccountId);
        // 验证原密码是否正确
        String userPassword = getUserPassword(userAccountModel.getSalt(), reqVo.getOldPassword());
        if (!userAccountModel.getPassword().equals(userPassword)) {
            throw new BusinessException("原密码错误！");
        }
        // 验证新密码和确认密码是否一致
        if (!reqVo.getPassword().equals(reqVo.getConfirmPassword())) {
            throw new BusinessException("新密码和确认密码不一致！");
        }
        // 修改用户密码
        String salt = CommonUtils.getPwdSalt();
        String userPassword1 = getUserPassword(salt, reqVo.getPassword());
        userAccountModel.setUpdateBy(currentUserAccountId);
        userAccountModel.setUpdateTime(new Date());
        userAccountModel.setSalt(salt);
        userAccountModel.setPassword(userPassword1);
        userAccountMapper.updateById(userAccountModel);

    }

    @Override
    public void resetPassword(Long id) {
        UserAccountModel userAccountModel = new UserAccountModel();
        String salt = CommonUtils.getPwdSalt();
        String userPassword = getUserPassword(salt, CommonConstant.USER_DEFAULT_PASSWORD);
        userAccountModel.setId(id);
        userAccountModel.setSalt(salt);
        userAccountModel.setPassword(userPassword);
        userAccountModel.setUpdateBy(jwtUtils.getCurrentUserAccountId());
        userAccountModel.setUpdateTime(new Date());
        userAccountMapper.updateById(userAccountModel);
    }

    @Override
    public ResultResponseEnum checkUserToken() {
        String requestURI = request.getRequestURI();
        String method = request.getMethod();

        // 如果不是api开头的则不验证
        if (!requestURI.startsWith("/api/")) {
            return ResultResponseEnum.SUCCESS;
        }

        if (requestURI.startsWith("/api/centralControl/user/userLogin")) {
            return ResultResponseEnum.SUCCESS;
        }
        try {
            Long currentUserAccountId = jwtUtils.getCurrentUserAccountId();
            if (ObjectUtils.isEmpty(currentUserAccountId)) {
                return ResultResponseEnum.TOKEN_INVALID;
            }
        } catch (Exception e) {
            return ResultResponseEnum.TOKEN_INVALID;
        }

        // TODO 判断用户是否此菜单权限
        return ResultResponseEnum.SUCCESS;
    }

    @Override
    public Map<Long, UserAccountModel> getAllUserMap() {
        Map<Long, UserAccountModel> userAccountModelMap = new HashMap<>(64);
        QueryWrapper<UserAccountModel> queryWrapper = new QueryWrapper<>();
        //queryWrapper.eq(UserAccountModel.DEL_FLAG, DeleteFlagEnum.NO.getCode());
        List<UserAccountModel> userAccountModels = userAccountMapper.selectList(queryWrapper);
        for (UserAccountModel userAccountModel : userAccountModels) {
            userAccountModelMap.put(userAccountModel.getId(), userAccountModel);
        }
        return userAccountModelMap;
    }


    /**
     * 返回用户的加密密码
     *
     * @param salt     密码盐
     * @param password 原明文密码
     * @return String
     */
    private String getUserPassword(String salt, String password) {
        return MD5Utils.string2MD5(salt + password);
    }

    /**
     * 添加用户角色信息
     *
     * @param userAccountId
     * @param roleIdList
     */
    private void addRole(Long userAccountId, List<Long> roleIdList) {
        // 添加用户角色信息
        if (!CollectionUtils.isEmpty(roleIdList)) {
            for (Long roleId : roleIdList) {
                UserAccountRoleModel userAccountRoleModel = new UserAccountRoleModel();
                userAccountRoleModel.setUserAccountId(userAccountId);
                userAccountRoleModel.setRoleId(roleId);
                userAccountRoleMapper.insert(userAccountRoleModel);
            }
        }
    }
}
